﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;

namespace SmartPowerHub.Communication.Modbus
{
    public interface IModbus : IDisposable, ICommunication
    {

        #region 写入
        Task<ModbusResponse> WriteMulti<T>(ushort address, T[] values, byte slaveAddress = 0x01, FunctionCode functionCode = FunctionCode.WriteMultipleRegisters);

        Task<ModbusResponse> WriteUInit16(ushort address, ushort value, byte slaveAddress = 0x01, FunctionCode functionCode = FunctionCode.WriteSingleRegister);

        Task<ModbusResponse> WriteUInit32(ushort address, uint value, byte slaveAddress = 0x01, FunctionCode functionCode = FunctionCode.WriteMultipleRegisters);

        Task<ModbusResponse> WriteS16(ushort address, short value, byte slaveAddress = 0x01, FunctionCode functionCode = FunctionCode.WriteSingleRegister);

        Task<ModbusResponse> WriteS32(ushort address, int value, byte slaveAddress = 0x01, FunctionCode functionCode = FunctionCode.WriteMultipleRegisters);

        Task<ModbusResponse> WriteDouble(ushort address, double value, byte slaveAddress = 0x01, FunctionCode functionCode = FunctionCode.WriteMultipleRegisters);

        Task<ModbusResponse> WriteFloat(ushort address, float value, byte slaveAddress = 0x01, FunctionCode functionCode = FunctionCode.WriteMultipleRegisters);

        Task<ModbusResponse> WriteString(ushort address, string value, byte slaveAddress = 0x01, FunctionCode functionCode = FunctionCode.WriteMultipleRegisters);

        #endregion

        #region 读取
        Task<ModbusResponse<T>> Read<T>(FunctionCode functionCode, ushort startAddress, ushort count, byte slaveAddress = 0x01);
        Task<ModbusResponse<ushort>> ReadUInit16(FunctionCode functionCode, ushort startAddress, ushort count = 1, byte slaveAddress = 0x01);
        Task<ModbusResponse<uint>> ReadUInt32(FunctionCode functionCode, ushort startAddress, ushort count = 2, byte slaveAddress = 0x01);
        Task<ModbusResponse<short>> ReadS16(FunctionCode functionCode, ushort startAddress, ushort count = 1, byte slaveAddress = 0x01);
        Task<ModbusResponse<int>> ReadS32(FunctionCode functionCode, ushort startAddress, ushort count = 2, byte slaveAddress = 0x01);
        Task<ModbusResponse<double>> ReadDouble(FunctionCode functionCode, ushort startAddress, ushort count = 4, byte slaveAddress = 0x01);
        Task<ModbusResponse<float>> ReadFloat(FunctionCode functionCode, ushort startAddress, ushort count = 1, byte slaveAddress = 0x01);
        Task<ModbusResponse<string>> ReadString(FunctionCode functionCode, ushort startAddress, ushort count, byte slaveAddress = 0x01);

        #endregion
    }

    public enum ModbusType : int
    {
        TCP,
        RTU
    }
    /// <summary>
    /// 功能码枚举
    /// </summary>
    public enum FunctionCode : byte
    {
        ReadHoldingRegisters = 0x03,
        ReadInputRegisters = 0x04,
        WriteSingleRegister = 0x06,
        WriteMultipleRegisters = 0x10,
        ReadWriteMultipleRegisters = 0x17
    }

    public enum EndianFormat
    {
        /// <summary>
        /// Big-Endian
        /// 大端序 ABCD
        /// </summary>
        ABCD = 0,
        /// <summary>
        /// Big-endian byte swap（大端Byte swap）
        /// 中端序 BADC, PDP-11 风格
        /// </summary>
        BADC = 1,
        /// <summary>
        /// Little-endian byte swap（小端Byte swap）
        /// 中端序 CDAB, Honeywell 316 风格
        /// </summary>
        CDAB = 2,
        /// <summary>
        /// Little-Endian
        /// 小端序 DCBA
        /// </summary>
        DCBA = 3,
    }

    public enum StringFormat
    {
        UTF8,
        ASCII
    }
}
